package usw.minimongodb.server;



import com.google.gson.Gson;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * Created by Mark on 2017/6/24.
 */
public class MongoDbServer implements MongoDbInterface {

    private static String  dbPath;
    private static final String _uuid = "uuid";

    /**
     *
     * @param path
     */
    public void createDataBase(String path, String tableName) {

        FileOutputStream xmlFile = null;

        //  save an instance of the dbPath
        dbPath = path;

        try {
            xmlFile = new FileOutputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Document doc = new Document();
        Element root = new Element("database");

        Element tb1 = new Element("table");
        tb1.setAttribute("name", tableName);
        Element tb2 = new Element("table");
        tb2.setAttribute("name", "system.indexs");
        Element tb3 = new Element("table");
        tb3.setAttribute("name", "system.users");

        root.addContent(tb1);
        root.addContent(tb2);
        root.addContent(tb3);

        doc.setRootElement(root);

        XMLOutputter out = new XMLOutputter();

        try {
            out.output(doc, xmlFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("-------create database success-------");
    }

    /**
     *
     * @param path
     * @return
     */
    public int establishConnection(String path) {

        dbPath = path;

        return 0;
    }

    /**
     *
     * @param tablename
     * @return
     */
    public List<Map> loadTableData(String tablename) {

        List<Map> maps = new ArrayList<Map>();
        Gson gson = new Gson();

        FileInputStream xmlFile = null;

        try {
            xmlFile = new FileInputStream(MongoDbServer.dbPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SAXBuilder saxBuilder = new SAXBuilder();
        Document doc = null;

        try {
            doc = saxBuilder.build(xmlFile);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Element root = doc.getRootElement();
        List<Element>   tables = root.getChildren();

        for (Element table : tables)
        {
            if  (table.getAttributeValue("name").equals(tablename))
            {
                //  Found table, do data enumeration
                List<Element> datas = table.getChildren();
                for (Element data : datas)
                {
                    String  text = data.getText();
                    if (text != null)
                    {
                        Map map = gson.fromJson(text, Map.class);
                        maps.add(map);
                    }
                }
            }
        }
        return maps;
    }

    /**
     *
     * @param tableName
     * @param po
     * @return
     */
    public boolean addData(String tableName, Object po) {

        boolean         bDataInsertion = false;
        Gson    gson = new Gson();

        FileInputStream xmlFile = null;

        System.out.println("addData() has been called.");

        try
        {
            xmlFile = new FileInputStream(MongoDbServer.dbPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SAXBuilder saxBuilder = new SAXBuilder();
        Document doc = null;

        try {
            doc = saxBuilder.build(xmlFile);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Element root = doc.getRootElement();
        List<Element>   tables = root.getChildren();
        for (Element table : tables) {

            System.out.println("Enumerating " + table.getAttributeValue("name").toString());

            if (table.getAttributeValue("name").toString().equals(tableName)) {

                Element data = new Element("data");

                Map map = new HashMap<String, String>();
                map.put(_uuid, UUID.randomUUID().toString());

                String json = gson.toJson(po);
                Map mp2 = gson.fromJson(json, Map.class);
                map.putAll(mp2); //添加javabean的数据

                data.addContent(gson.toJson(map));
                table.addContent(data);

                System.out.println("Data has been added : " + data);

                break;
            }
        }

        XMLOutputter out = new XMLOutputter();
        try {
            out.output(doc, new FileOutputStream(MongoDbServer.dbPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        bDataInsertion = true;
        System.out.println("-------insert data success-------");

        return bDataInsertion;
    }

    /**
     *
     * @param tableName
     * @param po
     */
    public boolean updateData(String tableName, Object po)
    {
        Gson gson = new Gson();
        boolean bUpdateFlag = false;

        FileInputStream xmlFile = null;
        try {
            xmlFile = new FileInputStream(MongoDbServer.dbPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SAXBuilder saxBuilder = new SAXBuilder();
        Document doc = null;

        try {
            doc = saxBuilder.build(xmlFile);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Element root = doc.getRootElement();

        List<Element> tables = root.getChildren();

        for (Element table : tables) {
            if  (table.getAttributeValue("name").equals(tableName)){

                //  匹配数据表
                List<Element> datas = table.getChildren();
                for (Element data : datas) {

                    Map table_map = gson.fromJson(data.getText(), Map.class);
                    Map object_map = gson.fromJson(gson.toJson(po), Map.class);

                    if  (table_map.get(_uuid).equals(object_map.get(_uuid))){//匹配uuid

                        table_map.clear();
                        table_map.putAll(object_map);//更新
                        Element data_new = new Element("data");
                        data_new.setText(gson.toJson(table_map));
                        table.removeContent(data);
                        table.addContent(data_new);

                        System.out.println("Found the data to update : " + object_map.get(_uuid));
                        break;
                    }
                }
            }
        }

        XMLOutputter out = new XMLOutputter();

        try {
            out.output(doc, new FileOutputStream(MongoDbServer.dbPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        bUpdateFlag =  true;

        System.out.println("-------updateData success-------");

        return  bUpdateFlag;
    }

    /**
     *
     * @param tableName
     * @param po
     */
    public boolean deleteData(String tableName, Object po)
    {
        Gson gson = new Gson();
        boolean bDeleteFlag = false;

        FileInputStream xmlFile = null;

        try {
            xmlFile = new FileInputStream(MongoDbServer.dbPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        SAXBuilder saxBuilder = new SAXBuilder();
        Document doc = null;

        try {
            doc = saxBuilder.build(xmlFile);
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Element root = doc.getRootElement();

        List<Element> tables = root.getChildren();

        for (Element table : tables) {

            if  (table.getAttributeValue("name").equals(tableName)){ //匹配数据表

                List<Element> datas = table.getChildren();
                for (Element data : datas) {

                    Map map1 = gson.fromJson(data.getText(), Map.class);
                    Map map2 = gson.fromJson(gson.toJson(po), Map.class);
                    if  (map1.get(_uuid).equals(map2.get(_uuid))){//匹配uuid
                        table.removeContent(data);
                        break;
                    }
                }
            }
        }

        XMLOutputter out = new XMLOutputter();
        try {
            out.output(doc, new FileOutputStream(MongoDbServer.dbPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        bDeleteFlag = true;
        System.out.println("-------delete data success-------");
        return bDeleteFlag;
    }
}
